using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using GroupSix.Application.Services;
using GroupSix.Application.Dtos;
using System;
using Microsoft.AspNetCore.Builder;

namespace GroupSix.Api.Middleware;

/// <summary>
/// 通用操作日志自动记录中间件
/// </summary>
public class OperationLogMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<OperationLogMiddleware> _logger;

    public OperationLogMiddleware(RequestDelegate next, ILogger<OperationLogMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context, OperationLogService operationLogService)
    {
        var request = context.Request;
        var response = context.Response;
        var startTime = DateTime.UtcNow;
        var log = new CreateOperationLogRequestDto();
        try
        {
            // 获取用户信息
            var user = context.User;
            var nameIdentifier = user?.FindFirstValue(ClaimTypes.NameIdentifier);
            log.OperatorId = !string.IsNullOrEmpty(nameIdentifier) ? Guid.Parse(nameIdentifier) : Guid.Empty;
            log.OperatorName = user?.Identity?.Name ?? "匿名用户";

            // 基本请求信息
            log.Module = request.Path.Value?.Split('/')[2] ?? "unknown";
            log.OperationType = request.Method.ToLower();
            log.RequestUrl = request.Path;
            log.RequestMethod = request.Method;
            log.IpAddress = context.Connection.RemoteIpAddress?.ToString() ?? "unknown";
            log.UserAgent = request.Headers["User-Agent"].ToString();
            log.RequestParams = request.QueryString.HasValue ? request.QueryString.Value : "";
            log.Description = $"{log.OperatorName} {log.OperationType} {log.Module}";
            log.Details = "";
            log.Result = "success";
            log.ErrorMessage = "";
            log.ResponseStatusCode = 200;
            log.ExecutionTime = 0;
            // log.OperationTime = startTime; // 移除该行，由服务层自动补充

            // 读取Body参数（仅POST/PUT）
            if (request.Method == HttpMethods.Post || request.Method == HttpMethods.Put)
            {
                request.EnableBuffering();
                var reader = new System.IO.StreamReader(request.Body, leaveOpen: true);
                var body = await reader.ReadToEndAsync();
                request.Body.Position = 0;
                log.RequestParams += $";body={body}";
            }

            // 执行下一个中间件
            var sw = System.Diagnostics.Stopwatch.StartNew();
            await _next(context);
            sw.Stop();
            log.ExecutionTime = sw.ElapsedMilliseconds;
            log.ResponseStatusCode = response.StatusCode;
        }
        catch (Exception ex)
        {
            log.Result = "error";
            log.ErrorMessage = ex.Message;
            log.ResponseStatusCode = 500;
            _logger.LogError(ex, "操作日志中间件异常");
        }
        finally
        {
            try
            {
                // 只记录API接口（/api/开头）
                if (request.Path.StartsWithSegments("/api"))
                {
                    await operationLogService.CreateOperationLogAsync(log);
                }
            }
            catch (Exception ex2)
            {
                _logger.LogError(ex2, "写入操作日志失败");
            }
        }
    }
}

// 扩展方法
public static class OperationLogMiddlewareExtensions
{
    public static IApplicationBuilder UseOperationLogMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<OperationLogMiddleware>();
    }
} 